package com.hz.foodstalls.config;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hz.foodstalls.log.Slf4jLogFactory;
import com.hz.foodstalls.model.WechatInfo;
import com.hz.foodstalls.shiro.freemarker.ShiroTags;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.core.JFinal;
import com.jfinal.ext.activiti.WorkFlowController;
import com.jfinal.ext.activiti.main.StencilsetRestResource;
import com.jfinal.ext.activiti.model.ModelController;
import com.jfinal.ext.activiti.model.ModelEditorJsonRestResource;
import com.jfinal.ext.activiti.model.ModelSaveRestResource;
import com.jfinal.ext.activiti.rest.ProcessDefinitionDiagramLayoutResource;
import com.jfinal.ext.activiti.rest.ProcessInstanceDiagramLayoutResource;
import com.jfinal.ext.activiti.rest.ProcessInstanceHighlightsResource;
import com.jfinal.ext.config.JFinalConfigExt;
import com.jfinal.ext.handler.ContextPathHandler;
import com.jfinal.ext.plugin.activiti.ActivitiPlugin;
import com.jfinal.ext.plugin.quartz.QuartzPlugin;
import com.jfinal.ext.plugin.shiro.JdbcShiroPlugin;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.tx.TxByMethodRegex;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.render.FreeMarkerRender;
import com.jfinal.render.ViewType;
import com.jfinal.template.Engine;

/**
 * Created by foodstalls on 2016/2/16.
 */
public class WebConfig extends JFinalConfigExt {
    private Logger log = LoggerFactory.getLogger(WebConfig.class);
    protected List<Routes.Route> routes;

    @Override
    public void configMoreConstants(Constants constants) {
        PropKit.use("cfg.txt");
        constants.setViewType(ViewType.FREE_MARKER);
        constants.setError401View("/WEB-INF/errorpages/401.html");
        constants.setError403View("/WEB-INF/errorpages/403.html");
        constants.setError404View("/WEB-INF/errorpages/404.html");
        constants.setError500View("/WEB-INF/errorpages/500.html");
        FreeMarkerRender.getConfiguration().setSharedVariable("shiro", new ShiroTags());
        constants.setLogFactory(new Slf4jLogFactory());
        constants.setMaxPostSize(100000000);
        constants.setBaseUploadPath("e:/");
    }

    @Override
    public void configMoreRoutes(Routes routes) {
        List<Routes.Route> rots = new ArrayList<>();
        routes.add("/activiti/model", ModelController.class);// 工作流-模型
        routes.add("/activiti/workflow", WorkFlowController.class);// 工作流
        // 流程在线编辑器和流程跟踪所用路由
        routes.add("/activiti/process-instance/highlights", ProcessInstanceHighlightsResource.class);// modeler
        routes.add("/activiti/process-instance/diagram-layout", ProcessInstanceDiagramLayoutResource.class);// modeler
        routes.add("/activiti/process-definition/diagram-layout", ProcessDefinitionDiagramLayoutResource.class);// modeler
        routes.add("/activiti/modelEditor/save", ModelSaveRestResource.class);
        routes.add("/activiti/editor/stencilset", StencilsetRestResource.class);
        routes.add("/activiti/modelEditor/json", ModelEditorJsonRestResource.class);
        rots.addAll(routes.getRouteItemList());
        for (Routes r : Routes.getRoutesList()) {
            rots.addAll(r.getRouteItemList());
        }
        this.routes = rots;// shiro使用
    }

    @Override
    public void configMorePlugins(Plugins plugins) {
        plugins.add(new ActivitiPlugin());
        // plugins.add(new ShiroPlugin(this.routes));
        plugins.add(new JdbcShiroPlugin(this.routes));
        plugins.add(new EhCachePlugin());
        plugins.add(new QuartzPlugin("job.properties"));
    }

    @Override
    public void configTablesMapping(String s, ActiveRecordPlugin activeRecordPlugin) {

    }

    @Override
    public void configMoreInterceptors(Interceptors interceptors) {
        // 根据方法名做事务控制,Interceptors是针对controller层的，是无法拦截到services层（AOP）的事务，复杂的事务控制可以使用services形式在其中进行处理
        interceptors.add(new TxByMethodRegex("(.*save.*|.*update.*|.*delete.*)"));
        // interceptors.add(new ShiroInterceptor());
        log.info("TxByMethodRegex" + log.getClass().getName());
    }

    @Override
    public void configMoreHandlers(Handlers handlers) {
        handlers.add(new ContextPathHandler("ctx"));

    }

    @Override
    public void afterJFinalStarted() {
        // 多公众号时可以考虑使用数据库存储相关信息，在此处读取出来了全部都put进去，然后公众号配置的时候带上appId参数，根据appId从里面取
        List<WechatInfo> list = WechatInfo.dao.getAvailableWechat();
        for (WechatInfo wechatInfo : list) {
            WechatInfo.dao.putConfig(wechatInfo);
            // // 配置微信 API 相关参数
            // ApiConfig ac = new ApiConfig();
            // ac.setToken(wechatInfo.getToken());
            // ac.setAppId(wechatInfo.getAppid());
            // ac.setAppSecret(wechatInfo.getAppsecret());
            //
            // /**
            // * 是否对消息进行加密，对应于微信平台的消息加解密方式： 1：true进行加密且必须配置 encodingAesKey
            // * 2：false采用明文模式，同时也支持混合模式
            // */
            // boolean encrypt = StringUtil.isNotBlank(wechatInfo.getAeskey());
            // ac.setEncryptMessage(encrypt);
            // if (encrypt) {
            // ac.setEncodingAesKey(wechatInfo.getAeskey());
            // } else {
            // ac.setEncodingAesKey("not encode with aes");
            // }
            //
            // /**
            // * 多个公众号时，重复调用ApiConfigKit.putApiConfig(ac)依次添加即可，第一个添加的是默认。
            // */
            // ApiConfigKit.putApiConfig(ac);
        }
    }

    public static void main(String[] args) {
        // Eclipse
//        JFinal.start("src/main/webapp", 8088, "/", 5);
        // IDEA
         JFinal.start("src/main/webapp", 8088, "/");
    }

    @Override
    public void configEngine(Engine arg0) {
    }

}
